
#ifndef WISHMASTER_GENERICCAPTCHAFETCHER_IMPL_H
#define WISHMASTER_GENERICCAPTCHAFETCHER_IMPL_H

#include <QVariant>
#include <QDateTime>
#include <boost/bind.hpp>
#include <map>
#include "components/threadid.h"
#include "requestmanager.h"
#include "request.h"
#include "log.h"

namespace Wishmaster
{
	class GenericCaptchaFetcherImpl : public QObject
	{
		Q_OBJECT
	public:
		GenericCaptchaFetcherImpl() : m_requestManager(0)
		{
		}

		void setRequestManager(Wishmaster2::Network::RequestManager* requestManager)
		{
			m_requestManager = requestManager;
		}

		void setParams(const QVariantMap& params)
		{
			for(QVariantMap::const_iterator it = params.begin(); it != params.end(); ++it)
			{
				if(it.key() == "url_pattern")
				{
					m_urlPattern = it.value().toString();
				}
				else if(it.key() == "referer_pattern")
				{
					m_refererPattern = it.value().toString();
				}
				else if(it.key() == "url_thread_pattern")
				{
					m_urlThreadPattern = it.value().toString();
				}
				else if(it.key() == "referer_thread_pattern")
				{
					m_refererThreadPattern = it.value().toString();
				}
			}
		}

		void fetchCaptcha(const ThreadId& threadId)
		{
			Q_ASSERT(m_requestManager);
			QString urlstr = threadId.threadNumericId() == 0 ? m_urlThreadPattern : m_urlPattern;
			urlstr.replace("%CHAN%", threadId.chanName());
			urlstr.replace("%BOARD%", threadId.boardId());
			urlstr.replace("%THREADID%", QString::number(threadId.threadNumericId()));
			urlstr.replace("%RANDOM%", QString::number(qrand()));
			urlstr.replace("%TIME%", QString::number(QDateTime::currentDateTime().toTime_t()));
			//log(llDebug, "urlstr: %s", qPrintable(urlstr));
			Wishmaster2::Network::Url url(urlstr.toStdString());
			//log(llDebug, "path: %s", qPrintable(path));
			Wishmaster2::Network::RequestPtr request = m_requestManager->createRequest(url);

			m_threadIds[request->id()] = threadId;

			QString referer = threadId.threadNumericId() == 0 ? m_refererThreadPattern : m_refererPattern;
			referer.replace("%CHAN%", threadId.chanName());
			referer.replace("%BOARD%", threadId.boardId());
			referer.replace("%THREADID%", QString::number(threadId.threadNumericId()));
			request->setParameter("http:referer", referer.toStdString());
			request->connectSignalFinished(boost::bind(&GenericCaptchaFetcherImpl::finished, this, _1));
			m_requestManager->enqueueRequest(request);
		}

	private:
		void finished(int id)
		{
			auto it = m_threadIds.find(id);
			if(it == m_threadIds.end())
				return;
			ThreadId threadId = it->second;
			m_threadIds.erase(it);

			if(!threadId.isValid())
				return;

			Wishmaster2::Network::RequestPtr request = m_requestManager->request(id);
			Wishmaster2::Network::VectorPtr data = request->content();

			log(llDebug, "Captcha for thread: %s:%s:%d", qPrintable(threadId.chanName()), qPrintable(threadId.boardId()), threadId.threadNumericId());
			emit captcha(threadId, QByteArray(data->data(), data->size()));
		}

	signals:
		void captcha(const ThreadId& id, const QByteArray& arr);


	private:
		std::map<int, ThreadId> m_threadIds;
		Wishmaster2::Network::RequestManager* m_requestManager;
		QString m_urlPattern;
		QString m_refererPattern;
		QString m_urlThreadPattern;
		QString m_refererThreadPattern;
	};
}

#endif

